/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package l1j.server.server.clientpackets;

import static l1j.server.server.model.skill.L1SkillId.AREA_OF_SILENCE;
import static l1j.server.server.model.skill.L1SkillId.SILENCE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_POISON_SILENCE;

import java.util.Map;

import l1j.server.Config;
import l1j.server.server.ClientThread;
import l1j.server.server.GMCommands;
import l1j.server.server.datatables.MotionCommandsTable;
import l1j.server.server.datatables.MotionCommandsTable.AllMotionCommands;
import l1j.server.server.model.L1Clan;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.L1MonsterInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_ChatPacket;
import l1j.server.server.serverpackets.S_NpcChatPacket;
import l1j.server.server.serverpackets.S_PacketBox;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.utils.Random;

// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket

/**
 * 處理收到由客戶端傳來的聊天封包
 */
public class C_Chat extends ClientBasePacket {

	private static final String C_CHAT = "[C] C_Chat";

	public C_Chat(byte abyte0[], ClientThread clientthread) {
		super(abyte0);

		L1PcInstance pc = clientthread.getActiveChar();
		if (pc == null) {
			return;
		}

		int chatType = readC();
		String chatText = readS();
		if (chatText != null && chatText.length() > 130) {
			chatText = chatText.substring(0, 130);
		}

		if (pc.hasSkillEffect(SILENCE) || pc.hasSkillEffect(AREA_OF_SILENCE)
				|| pc.hasSkillEffect(STATUS_POISON_SILENCE)) {
			return;
		}
		if (pc.hasSkillEffect(1005)) { // 被魔封
			pc.sendPackets(new S_ServerMessage(242)); // 你從現在被禁止閒談。
			return;
		}
		
		Map<Integer, AllMotionCommands> allCommands = MotionCommandsTable.getInstance().getAllCommands();
		boolean isMotionCommand = false;
		if (chatText.startsWith("=") && !chatText.startsWith("=符文=")) {
			String[] newStr = chatText.split("=");
			boolean isPair = false; 
			if (newStr.length == 3) {
				for(L1PcInstance player: L1World.getInstance().getAllPlayers()) {
					if (player.getName().equalsIgnoreCase(newStr[2])) {
						isPair = true;
						break;
					}
				}
			}
			for (int i = 1; i <= allCommands.size(); i++) {
				String strCh = allCommands.get(i).getCommand_ch();
				String strEn = allCommands.get(i).getCommand_en();
				if (chatText.contains(strCh) || chatText.contains(strEn)) {
					if (isPair == false) {
						chatText = allCommands.get(i).getSingle_string_1() 
						+ pc.getName() + allCommands.get(i).getSingle_string_2();
					} else {
						chatText = allCommands.get(i).getPair_string_1() + pc.getName() 
									+ allCommands.get(i).getPair_string_2() + newStr[2] 
									 + allCommands.get(i).getPair_string_3();
					}
					break;
				} else if (i == allCommands.size()) {
					pc.sendPackets(new S_SystemMessage("查無此動作表情指令。"));
					return;
				}
			}
			isMotionCommand = true;
		}
		if (chatText.startsWith("=符文=")) {
			String[] runeName = {"A", "B", "C", "D", "E", "F"};
			int A = 0;
			int B = 0;
			int C = 0;
			int D = 0;
			int E = 0;
			int F = 0;
			int[] text = new int[90];
			boolean check = false;
			while (check == false) {
				A = 0;
				B = 0;
				C = 0;
				D = 0;
				E = 0;
				F = 0;
				for (int i = 0; i < 90; i++) {
					int chance = Random.nextInt(6);
					if (chance == 0) {
						A += 1;
					} else if (chance == 1) {
						B += 1;
					} else if (chance == 2) {
						C += 1;
					} else if (chance == 3) {
						D += 1;
					} else if (chance == 4) {
						E += 1;
					} else if (chance == 5) {
						F += 1;
					}
					text[i] = chance;
				}
				if (A == 15 && B == 15 && C == 15 && D == 15 && E == 15 && F == 15) {
					check = true;
				}
			}
//			for (int i = 0; i < 90; i++) {
//				int chance = Random.nextInt(6);
//				if (chance == 0) {
//					A += 1;
//				} else if (chance == 1) {
//					B += 1;
//				} else if (chance == 2) {
//					C += 1;
//				} else if (chance == 3) {
//					D += 1;
//				} else if (chance == 4) {
//					E += 1;
//				} else if (chance == 5) {
//					F += 1;
//				}
//				text[i] = chance;
//			}
			if (check == true) {
				for (int i = 0; i < 30; i++) {
					chatText = runeName[text[i]] 
					                    + runeName[text[i + 30]] 
					                               + runeName[text[i + 60]];
					pc.sendPackets(new S_SystemMessage("符文組" + (i + 1) + ": " + chatText));
				}
				return;
			} else  {
				pc.sendPackets(new S_SystemMessage("A:" + A + "B:" + B + "C:" + C + "D:" + D + "E:" + E + "F:" + F));
				pc.sendPackets(new S_SystemMessage("配對失敗。"));
				return;
			}
		}

		if (chatType == 0) { // 一般聊天
			if (pc.isGhost() && !(pc.isGm() || pc.isMonitor())) {
				return;
			}
			// GM指令
			if (chatText.startsWith(".") && (pc.isGm() || pc.isMonitor())) {
				String cmd = chatText.substring(1);
				GMCommands.getInstance().handleCommands(pc, cmd);
				return;
			}

			// 交易頻道
			// 本来はchatType==12になるはずだが、行頭の$が送信されない
			if (chatText.startsWith("$")) {
				String text = chatText.substring(1);
				chatWorld(pc, text, 12, isMotionCommand);
				if (!pc.isGm()) {
					pc.checkChatInterval();
				}
				return;
			}

			if (!pc.getExcludingList().contains(pc.getName())) {
				pc.sendPackets(new S_ChatPacket(pc, chatText,
						pc.getOpcodes().S_OPCODE_NORMALCHAT, 0, isMotionCommand));
			}
			for (L1PcInstance listner : L1World.getInstance()
					.getRecognizePlayer(pc)) {
				if (listner.getMapId() < 16384 || listner.getMapId() > 25088
						|| listner.getInnKeyId() == pc.getInnKeyId()) // 旅館內判斷
					if (!listner.getExcludingList().contains(pc.getName()))
						listner.sendPackets(new S_ChatPacket(pc, chatText,
								listner.getOpcodes().S_OPCODE_NORMALCHAT, 0, isMotionCommand));
			}
			// 怪物模仿
			for (L1Object obj : pc.getKnownObjects()) {
				if (obj instanceof L1MonsterInstance) {
					L1MonsterInstance mob = (L1MonsterInstance) obj;
					if (mob.getNpcTemplate().is_doppel()
							&& mob.getName().equals(pc.getName())
							&& !mob.isDead()) {
						mob.broadcastPacket(new S_NpcChatPacket(mob, chatText,
								0));
					}
				}
			}
		} else if (chatType == 2) { // 喊叫
			if (pc.isGhost()) {
				return;
			}

			if (!pc.getExcludingList().contains(pc.getName())) {
				pc.sendPackets(new S_ChatPacket(pc, chatText,
						pc.getOpcodes().S_OPCODE_NORMALCHAT, 2, isMotionCommand));
			}
			for (L1PcInstance listner : L1World.getInstance().getVisiblePlayer(
					pc, 50)) {
				if (listner.getMapId() < 16384 || listner.getMapId() > 25088
						|| listner.getInnKeyId() == pc.getInnKeyId()) // 旅館內判斷
					if (!listner.getExcludingList().contains(pc.getName()))
						listner.sendPackets(new S_ChatPacket(pc, chatText,
								listner.getOpcodes().S_OPCODE_NORMALCHAT, 2, isMotionCommand));
			}

			// 怪物模仿
			for (L1Object obj : pc.getKnownObjects()) {
				if (obj instanceof L1MonsterInstance) {
					L1MonsterInstance mob = (L1MonsterInstance) obj;
					if (mob.getNpcTemplate().is_doppel()
							&& mob.getName().equals(pc.getName())
							&& !mob.isDead()) {
						for (L1PcInstance listner : L1World.getInstance()
								.getVisiblePlayer(mob, 50)) {
							listner.sendPackets(new S_NpcChatPacket(mob,
									chatText, 2));
						}
					}
				}
			}
		} else if (chatType == 3) { // 全體聊天
			chatWorld(pc, chatText, chatType, isMotionCommand);
		} else if (chatType == 4) { // 血盟聊天
			if (pc.getClanid() != 0) { // 所屬血盟
				L1Clan clan = L1World.getInstance().getClan(pc.getClanname());
				int rank = pc.getClanRank();
				if ((clan != null)
						&& ((rank == L1Clan.CLAN_RANK_PUBLIC)
								|| (rank == L1Clan.CLAN_RANK_GUARDIAN) || (rank == L1Clan.CLAN_RANK_PRINCE))) {

					L1PcInstance[] clanMembers = clan.getOnlineClanMember();
					for (L1PcInstance listner : clanMembers) {
						if (!listner.getExcludingList().contains(pc.getName())) {
							if (listner.isShowClanChat() && chatType == 4)// 血盟
								listner.sendPackets(new S_ChatPacket(
										pc,
										chatText,
										listner.getOpcodes().S_OPCODE_GLOBALCHAT,
										4, isMotionCommand));
						}
					}
				}
			}
		} else if (chatType == 11) { // 組隊聊天
			if (pc.isInParty()) { // 組隊中

				L1PcInstance[] partyMembers = pc.getParty().getMembers();
				for (L1PcInstance listner : partyMembers) {
					if (!listner.getExcludingList().contains(pc.getName())) {
						if (listner.isShowPartyChat() && chatType == 11)// 組隊
							listner.sendPackets(new S_ChatPacket(pc, chatText,
									listner.getOpcodes().S_OPCODE_GLOBALCHAT,
									11, isMotionCommand));
					}
				}
			}
		} else if (chatType == 12) { // 交易聊天
			chatWorld(pc, chatText, chatType, isMotionCommand);
		} else if (chatType == 13) { // 連合血盟
			if (pc.getClanid() != 0) { // 在血盟中
				L1Clan clan = L1World.getInstance().getClan(pc.getClanname());
				int rank = pc.getClanRank();
				if ((clan != null)
						&& ((rank == L1Clan.CLAN_RANK_GUARDIAN) || (rank == L1Clan.CLAN_RANK_PRINCE))) {

					L1PcInstance[] clanMembers = clan.getOnlineClanMember();
					for (L1PcInstance listner : clanMembers) {
						int listnerRank = listner.getClanRank();
						if (!listner.getExcludingList().contains(pc.getName())
								&& ((listnerRank == L1Clan.CLAN_RANK_GUARDIAN) || (listnerRank == L1Clan.CLAN_RANK_PRINCE))) {
							listner.sendPackets(new S_ChatPacket(pc, chatText,
									listner.getOpcodes().S_OPCODE_GLOBALCHAT,
									13, isMotionCommand));
						}
					}
				}
			}
		} else if (chatType == 14) { // 聊天組隊
			if (pc.isInChatParty()) { // 聊天組隊
				L1PcInstance[] partyMembers = pc.getChatParty().getMembers();
				for (L1PcInstance listner : partyMembers) {
					if (!listner.getExcludingList().contains(pc.getName())) {
						listner.sendPackets(new S_ChatPacket(pc, chatText,
								listner.getOpcodes().S_OPCODE_NORMALCHAT, 14, isMotionCommand));
					}
				}
			}
		}
		if (!pc.isGm()) {
			pc.checkChatInterval();
		}
	}

	private void chatWorld(L1PcInstance pc, String chatText, int chatType, boolean isMotionCommand) {
		if (pc.isGm()) {
			for (L1PcInstance listener : L1World.getInstance().getAllPlayers()) {
				listener.sendPackets(new S_ChatPacket(pc, chatText, listener
						.getOpcodes().S_OPCODE_GLOBALCHAT, chatType, isMotionCommand));
			}
		} else if (pc.getLevel() >= Config.GLOBAL_CHAT_LEVEL) {
			if (L1World.getInstance().isWorldChatElabled()) {
				if (pc.get_food() >= 6) {
					pc.set_food(pc.get_food() - 5);

					pc.sendPackets(new S_PacketBox(S_PacketBox.FOOD, pc
							.get_food()));
					for (L1PcInstance listner : L1World.getInstance()
							.getAllPlayers()) {
						if (!listner.getExcludingList().contains(pc.getName())) {
							if (listner.isShowTradeChat() && (chatType == 12)) {
								listner.sendPackets(new S_ChatPacket(
										pc,
										chatText,
										listner.getOpcodes().S_OPCODE_GLOBALCHAT,
										chatType, isMotionCommand));
							} else if (listner.isShowWorldChat()
									&& (chatType == 3)) {
								listner.sendPackets(new S_ChatPacket(
										pc,
										chatText,
										listner.getOpcodes().S_OPCODE_GLOBALCHAT,
										chatType, isMotionCommand));
							}
						}
					}
				} else {
					pc.sendPackets(new S_ServerMessage(462)); // 你太過於饑餓以致於無法談話。
				}
			} else {
				pc.sendPackets(new S_ServerMessage(510)); // 現在ワールドチャットは停止中となっております。しばらくの間ご了承くださいませ。
			}
		} else {
			pc.sendPackets(new S_ServerMessage(195, String
					.valueOf(Config.GLOBAL_CHAT_LEVEL))); // 等級
															// %0
															// 以下的角色無法使用公頻或買賣頻道。
		}
	}

	@Override
	public String getType() {
		return C_CHAT;
	}
}
